﻿using DA.Core.Common;
using DA.Core.Plcs;
using DA.DataBase.DataBaseContext;
using DA.HMI.Controls;
using DA.HMI.Models;
using Microsoft.EntityFrameworkCore.ValueGeneration;
using Microsoft.Extensions.Primitives;
using Prism.Commands;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

namespace DA.HMI.ViewModels
{
    public class MainViewModel : BindableBase
    {
        private IContainerProvider containerProvider;
        private IDialogService dialog;
        private IRegionManager regionManager;
        private Configurations configurations;
        private Hardcodet.Wpf.TaskbarNotification.TaskbarIcon notify;
        private IMessage messageManager;
        private readonly CancellationToken ct;
        private Dictionary<string, HcRichTextBox> textBoxDics = new Dictionary<string, HcRichTextBox>();
        public MainViewModel(IContainerProvider containerProvider, IDialogService dialog,IRegionManager regionManager)
        {
            ct = new CancellationTokenSource().Token;
            this.containerProvider = containerProvider;
            this.dialog = dialog;
            CurrentMode = "浏览";
            this.regionManager = regionManager;

            TreeViews.Add(new TreeViewItemModel
            {
                MenuIcon = "Home",
                MenuHeader = "ProcessState",
                TargetView = "ProcessStateView"
            });
            TreeViews.Add(new TreeViewItemModel
            {
                MenuIcon = "",
                MenuHeader = "Log",
                TargetView = "LogView"
            });
        }
      
        public ICommand LoadedCmd
        {
            get => new DelegateCommand<object>((obj) =>
            {
                regionManager.RequestNavigate("MainRegion", "ProcessStateView");

                notify = obj as Hardcodet.Wpf.TaskbarNotification.TaskbarIcon;

                configurations = containerProvider.Resolve<Configurations>();

                messageManager = containerProvider.Resolve<IMessage>();

                var db= containerProvider.Resolve<IDbContext>() as MySqlDbContext;
                db.Materials.Select(p => p.ProcessId);
               
                StationJson = File.ReadAllText(@$"{AppDomain.CurrentDomain.BaseDirectory}\Common\appsetting.json");
                //station
                configurations.Appsetting.Stations.ForEach(p =>
                {
                    

                    //log页面
                    var textbox = new HcRichTextBox();
                    textBoxDics.Add(p.StationId, textbox);
                    LogTabs.Add(new TabItem
                    {
                        Header = p.StationId,
                        Content = textbox,
                    });
                });
                //plc 
                configurations.Appsetting.Plcs.ForEach(p =>
                {
                    PlcData.Add(new PlcModel
                    {
                        ID = p.PlcID,
                        IP = p.IpAddress,
                        Port = p.Port,
                        HeartBeat = p.HeartBeat
                    });
                });

                Task.Run(StartMessage);
            });
        }
        public ICommand SelectedItemChangedCmd
        {
            get => new DelegateCommand<object>(obj =>
            {
                var item = obj as TreeViewItemModel;

                switch (item.MenuHeader)
                {
                    case "ProcessState":regionManager.RequestNavigate("MainRegion", "ProcessStateView"); break;
                    case "Log": regionManager.RequestNavigate("MainRegion", "LogView"); break;
                    default: break;
                }
            });
        }

        private void StartMessage()
        {
            while (!ct.IsCancellationRequested)
            {
                if (messageManager.MessageBlocks.TryTake(out var item, 500, ct))
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        textBoxDics.FirstOrDefault(p => p.Key == item.Source).Value.AddText = $"{item.Time}--{item.Message.ToString()}";
                    });
                }
            }
        }
        public ICommand ShowLoginCmd
        {
            get => new DelegateCommand(() =>
            {
                DialogParameters paras = new DialogParameters();

                dialog.ShowDialog("LoginView", paras, (callback) =>
                {
                    if (callback.Result == ButtonResult.OK)
                    {
                        ConfigureIsReadOnly = false;
                        CurrentMode = "编辑";
                    }
                });
            });
        }
        public ICommand LoginOutCmd
        {
            get => new DelegateCommand(() =>
            {
                ConfigureIsReadOnly = true;
                CurrentMode = "浏览";
            });
        }
        public ICommand SaveCmd
        {
            get => new DelegateCommand(() =>
            {
                var path = @$"{AppDomain.CurrentDomain.BaseDirectory}\Common\appsetting.json";
                File.WriteAllTextAsync(path, StationJson);
            });
        }
        public ICommand StateChangedCmd
        {
            get => new DelegateCommand<object>((obj) =>
            {
                var winState = obj as Window;
                switch (winState.WindowState)
                {
                    case WindowState.Minimized:
                        Application.Current.MainWindow.Hide();
                        break;
                    case WindowState.Maximized:
                        break;
                }
            });
        }
        public ICommand CloseCmd
        {
            get => new DelegateCommand(() =>
            {
                notify.Dispose();
            });
        }
        public ICommand Exit
        {
            get => new DelegateCommand(() =>
            {
                notify.Dispose();
                Environment.Exit(0);
            });
        }
        public ICommand Show
        {
            get => new DelegateCommand(() =>
            {
                Application.Current.MainWindow.Show();
            });
        }
        public DelegateCommand<object> Hide
        {
            get => new DelegateCommand<object>((obj) =>
            {
                Application.Current.MainWindow.Hide();
            });
        }

        private ObservableCollection<TreeViewItemModel> treeViews = new ObservableCollection<TreeViewItemModel>();

        public ObservableCollection<TreeViewItemModel> TreeViews
        {
            get { return treeViews; }
            set { SetProperty(ref treeViews, value); }
        }


      

        private ObservableCollection<PlcModel> plcData = new ObservableCollection<PlcModel>();

        public ObservableCollection<PlcModel> PlcData
        {
            get { return plcData; }
            set { SetProperty(ref plcData, value); }
        }

        private ObservableCollection<TabItem> logTabs = new ObservableCollection<TabItem>();

        public ObservableCollection<TabItem> LogTabs
        {
            get { return logTabs; }
            set { SetProperty(ref logTabs, value); }
        }

        private string stationJson;

        public string StationJson
        {
            get { return stationJson; }
            set { SetProperty(ref stationJson, value); }
        }

        private bool configureIsReadOnly = true;

        public bool ConfigureIsReadOnly
        {
            get { return configureIsReadOnly; }
            set { SetProperty(ref configureIsReadOnly, value); }
        }
        private string currentMode;

        public string CurrentMode
        {
            get { return currentMode; }
            set { SetProperty(ref currentMode, value); }
        }


        //private ObservableCollection<StationModel> configureData = new ObservableCollection<StationModel>();

        //public ObservableCollection<StationModel> ConfigureData
        //{
        //    get { return configureData; }
        //    set { SetProperty(ref configureData, value); }
        //}

    }
}